import UtilFuncs from '../common/tools/utilfuncs.js'
var funcs = UtilFuncs.UtilFuncs;

import GlobalConst from '../common/globalConst.js'
var global = GlobalConst.GlobalConst;
import LGXCOM from '../common/common.js'

import {LGXEnums}  from '../common/sysenum.js';

import { LineTangent2CircleSvc } from './linetangent2circlesvc.js';

//图形特征点
class TGaphPTFeature {
    constructor(mousePt, featureWolrdPT) {
        this.ptInfo = {pt:null,kind:LGXEnums.AuxPointKind.none};
        this.ptInfo.pt = new LGXCOM.LGXPoint();
        this.ptInfo.pt.clone(featureWolrdPT.pt);
        this.ptInfo.kind = featureWolrdPT.kind;

        this.offset = new LGXCOM.LGXPoint();
        this.offset.x = featureWolrdPT.x - mousePt.x;
        this.offset.y = featureWolrdPT.y - mousePt.y;
    }
}

//图形特征
class TGraphFeature {
    constructor(graph) {
        this.refGraph = graph;
        this.featurePtLst = new Array();//特征点列表，世界坐标
    }
}

var PointSnapSvc = {}



PointSnapSvc.snapMouse2OtherGraphPTFeature = function (pDataMng, mousePoint, ignoreSelf,sureAbsorbPtFlag) {
    // if (pDataMng)
    // return null;

    let testPt = {x:550,y:500};
    let testdis = funcs.distancePoint(mousePoint,testPt,1);
    if (testdis < 2){
        console.log();
    }

    var pCurentGraph = pDataMng.getCurentGraph();
    let translateFlag = true;
    if (pCurentGraph) {
        translateFlag = pCurentGraph.chkInTranslating();
    }

    let flag = false;
    let absorbRstInfo = LineTangent2CircleSvc.snapLine2Circle(pCurentGraph, pDataMng, mousePoint);
    if (!absorbRstInfo || (absorbRstInfo && !absorbRstInfo.flag)) {
        absorbRstInfo = this.absorbMousePos2SurroundGraph(pDataMng, mousePoint, null,translateFlag);
    }
    let auxDataMng = pDataMng.getAuxDataManager();
    if (absorbRstInfo && absorbRstInfo.flag){
        flag = true;
        // if (sureAbsorbPtFlag)
        {
            mousePoint.clone(absorbRstInfo.ptInfo.pt);
            auxDataMng.setAbsorbPointPos(mousePoint);
            auxDataMng.setAbsorbPointKind(absorbRstInfo.ptInfo.kind);
        }
    }
    else{
        auxDataMng.setAbsorbPointKind(LGXEnums.AuxPointKind.none);
    }
    return flag;
}

PointSnapSvc.absorbMousePos2SurroundGraph = function (pDataMng, mousePoint, pCurentGraph,translateFlag) {
    let absorbFlag = false;
    let abortPtInfo = null;
    var result = this.snapPt2Surround(pDataMng, mousePoint, pCurentGraph, translateFlag);
    let auxDataMng = pDataMng.getAuxDataManager();
    if (result.ptInfo) {
        abortPtInfo = result.ptInfo;
        auxDataMng.setAbsorbPointPos(mousePoint);
        auxDataMng.setAbsorbPointDis(1);
        absorbFlag = true;
    }
    else {
        auxDataMng.setAbsorbPointDis(0);
    }
    return {ptInfo:abortPtInfo,flag:absorbFlag};
}

PointSnapSvc.snapPt2Surround = function (pDataMng, mousePoint, pCurentGraph, translateFlag) {
    //先检测尝试对齐主特征点
    var featureFuncs = this.getGraphMainPtFeature;
    let rst = this.snapPt2SurroundByFuncType(pDataMng, mousePoint, pCurentGraph, translateFlag, featureFuncs);

    if (mousePoint.x > 145 && mousePoint.x < 155
        && mousePoint.y > 95 && mousePoint.y < 105) {
        console.log("dscs");
    }

    //然后再检测尝试对齐次要特征点,以当前点为参考，在吸附范围内图上的点
    if (!rst || (rst && !rst.ptInfo)) {
        featureFuncs = this.getGraphSubPtFeature;
        rst = this.snapPt2SurroundByFuncType(pDataMng, mousePoint, pCurentGraph, translateFlag, featureFuncs, rst);
    }
    return rst;
}


PointSnapSvc.snapPt2SurroundByFuncType = function (pDataMng, mousePoint, pCurentGraph, translateFlag,
    featureFuncs, preAbsorbRet) {
    let scaling = pDataMng.getScaling();
    var minDis = -1;
    let abortPoint = null;
    if (preAbsorbRet) {
        minDis = preAbsorbRet.dis;
        abortPoint = preAbsorbRet.pt;
    }

    let size = global.SelectGap / scaling;
    let mouseRect = new LGXCOM.LGXRect();
    mouseRect.left = mousePoint.x - size;
    mouseRect.right = mousePoint.x + size;
    mouseRect.bottom = mousePoint.y - size;
    mouseRect.top = mousePoint.y + size;
    
    var graphLst = pDataMng.getAllVisibleGraphs();
    var count = graphLst.length;

    //先检测尝试对齐主特征点
    for (let i = 0; i < count; i++) {
        let pGraph = graphLst[i];
        if (!funcs.chkOverlap(mouseRect, pGraph.getZone())) {
            continue;
        }
        if (!this.chkCanAbsorb(pCurentGraph, pGraph)) {
            continue;
        }

        var feature = featureFuncs(pGraph, mousePoint);
        for (var n = 0; n < feature.featurePtLst.length; n++) {
            let tempPtFeature = feature.featurePtLst[n];
            let chkRst = this.chkMayAlgin(mousePoint, tempPtFeature.ptInfo.pt, scaling, translateFlag);
            if (chkRst.flag && !this.chkIsFarApart(mousePoint, tempPtFeature)) {
                //如果是拉开的，两个边界越来越远的，也不用吸附，靠近才需要
                //否则会导致吸附后无法分开
                if (minDis < 0) {
                    minDis = chkRst.dis;
                    abortPoint = tempPtFeature.ptInfo;
                }
                else if (minDis > chkRst.dis) {
                    minDis = chkRst.dis;
                    abortPoint = tempPtFeature.ptInfo;
                }
            }
        }
    }
    var rst = { ptInfo: abortPoint, dis: minDis };
    return rst;
}

PointSnapSvc.chkMayAlgin = function (mousePoint, dstPt, scaling, translateFlag) {
    let canNotAlginRst = { flag: false, dis: -1 };
    let flag = false;
    let dis = funcs.distancePoint(mousePoint, dstPt, 1);
    if (!translateFlag) {
        //变形修改情况下，已对齐的边不再判断
        if (dis < global.ZERO_4E) {
            return canNotAlginRst;
        }
    }
    let absorbDis = global.SelectGap / scaling;
    if (dis < absorbDis) {
        flag = true;
    }
    return { flag, dis };
}

PointSnapSvc.chkIsFarApart = function (mousePoint, dstPtFeature, originOffsetPt) {
    let flag = false;
    return flag;
}

//获取当前被编辑图形的特征点和相对于当前鼠标的偏移队列
//当前图形可能是正在被拖动的，也可能是将要绘制，但是还没有启动绘制的
//计算移动时图形的特征点坐标ptlst和每个特征的相对于起始移动坐标点的偏移队列offsetlst
PointSnapSvc.getGraphMainPtFeature = function (graph, mousePoint) {
    if (!graph) {
        return null;
    }
    var tFeaturePTLst = new Array();
    graph.getMainFeaturePTLst(tFeaturePTLst);
    let graphFeature = PointSnapSvc.getGraphPtFeature(graph, mousePoint, tFeaturePTLst);
    return graphFeature;
}

PointSnapSvc.getGraphSubPtFeature = function (graph, mousePoint) {
    if (!graph) {
        return null;
    }
    var tFeaturePTLst = new Array();
    graph.getSubFeaturePTLst(tFeaturePTLst, mousePoint);
    let graphFeature = PointSnapSvc.getGraphPtFeature(graph, mousePoint, tFeaturePTLst);
    return graphFeature;
}

PointSnapSvc.getGraphPtFeature = function (graph, mousePoint, tFeaturePTLst) {
    let graphFeature = new TGraphFeature(graph);
    let symScope = graph.getLocalZone();
    graphFeature.width = symScope.width();
    graphFeature.height = symScope.height();

    tFeaturePTLst.forEach(ptInfo => {
        let featurePT = new TGaphPTFeature(mousePoint, ptInfo);
        graphFeature.featurePtLst.push(featurePT);
    });
    tFeaturePTLst.length = 0;
    return graphFeature;
}


PointSnapSvc.getInterPoints = function (dstGraph, tAllGraphLst) {
    let rstArr = [];
    switch (dstGraph.m_graphType) {
        case LGXEnums.LGXGraphType.LineGraph_type:
            rstArr = this.findGraphInterLine(dstGraph, tAllGraphLst);
            break;

        case LGXEnums.LGXGraphType.CircleGraph_type:
            rstArr = this.findGraphInterCircle(dstGraph, tAllGraphLst);
            break;

        case LGXEnums.LGXGraphType.ArcGraph_type:
            rstArr = this.findGraphInterArc(dstGraph, tAllGraphLst);
            break;
    }
    return rstArr;
}

PointSnapSvc.findGraphInterLine = function (curentGraph, tAllGraphLst) {
    let toltalArr = [];
    let curentRect = curentGraph.getZone();
    let position = curentGraph.getPosCopy();
    let prePoint = position.posList[0];
    for (let i = 1; i < position.posList.length; i++) {
        let nextPoint = position.posList[i];
        for (let n = 0; n < tAllGraphLst.length; n++) {
            let dstGraph = tAllGraphLst[n];
            if (dstGraph.getUseful() == 1 && curentGraph != dstGraph && dstGraph.getFinish()) {
                if (!funcs.chkOverlap(dstGraph.getZone(), curentRect)) {
                    continue;
                }
                let rstArr = chkintersvc.ChkInterSvc.check4Line(dstGraph, prePoint, nextPoint, null);
                if (rstArr) {
                    rstArr.forEach(p => {
                        toltalArr.push(p);
                    });
                }
            }
        }
        prePoint = nextPoint;
    }
    return toltalArr;
}


PointSnapSvc.findGraphInterCircle = function (curentGraph, tAllGraphLst) {
    let toltalArr = [];
    let curentRect = curentGraph.getZone();
    for (let i = 0; i < tAllGraphLst.length; i++) {
        let dstGraph = tAllGraphLst[i];
        if (dstGraph.getUseful() == 1 && curentGraph != dstGraph && dstGraph.getFinish()) {
            if (!funcs.chkOverlap(dstGraph.getZone(), curentRect)) {
                continue;
            }
            let rstArr = chkintersvc.ChkInterSvc.check4Circle(dstGraph, curentGraph.getPosCopy(), null);
            if (rstArr) {
                rstArr.forEach(p => {
                    toltalArr.push(p);
                });
            }
        }
    }
    return toltalArr;
}

PointSnapSvc.findGraphInterArc = function (curentGraph, tAllGraphLst) {
    let toltalArr = [];
    let curentRect = curentGraph.getZone();
    for (let i = 0; i < tAllGraphLst.length; i++) {
        let dstGraph = tAllGraphLst[i];
        if (dstGraph.getUseful() == 1 && curentGraph != dstGraph && dstGraph.getFinish()) {
            if (!funcs.chkOverlap(dstGraph.getZone(), curentRect)) {
                continue;
            }
            let rstArr = chkintersvc.ChkInterSvc.check4Arc(dstGraph, curentGraph.getPosCopy(), null);
            if (rstArr) {
                rstArr.forEach(p => {
                    toltalArr.push(p);
                });
            }
        }
    }
    return toltalArr;
}

PointSnapSvc.chkCanAbsorb = function (pCurentGraph, pDstGraph) {
    if (pCurentGraph == pDstGraph
        || pDstGraph.getFinish() == 0
        || pDstGraph.getUseful() != 1
        || pDstGraph.getModifing() == 1
        || pDstGraph.m_graphType == LGXEnums.LGXGraphType.Combine_type
        || pDstGraph.m_graphType == LGXEnums.LGXGraphType.TextGraph_type
        || pDstGraph.m_graphType == LGXEnums.LGXGraphType.DimTextGraph_type
        || pDstGraph.m_graphType == LGXEnums.LGXGraphType.CADText_type
        || pDstGraph.m_graphType == LGXEnums.LGXGraphType.FastToolPanel_type
        || funcs.group(pDstGraph.getType()) == global.dimGroup
    ) {
        return false;
    }

    let flag = true;
    if (pCurentGraph) {
        flag = false;
        let rect1 = pCurentGraph.getZone();
        let rect2 = pDstGraph.getZone();
        if (funcs.chkOverlap(rect1, rect2)) {
            flag = true;
        }
    }
    return flag;
}

export default { PointSnapSvc, TGaphPTFeature, TGraphFeature }


